#include "oslib_plus_wifi_at.h"
#include <string.h>

#if 0
/**
 * @brief 通过串口发送AT指令, 建立UDP连接
 * 
 * @param huart 目标端口 
 * @param remote_ip 要连接的目标ip地址
 * @param remote_port 要连接的目标端口
 * @param local_port 参与连接的本地端口
 */
void OSLIB_PLUS_Wifi_UDP_Connect(UART_HandleTypeDef *huart, const char *remote_ip, uint16_t remote_port, uint16_t local_port)
{
    uprintf_to(&huart, "AT+CIPSTART=\"UDP\",\"%s\",%hu,%hu\r\n", remote_ip, remote_port, local_port);
}

uint8_t OSLIB_PLUS_Wifi_UDP_Connect_Check(const char *src)
{
    // if (strncmp(src, "OK", 2) == 0)
    //     return 0;
    // else if (strncmp(src, "ERROR", 5) == 0)
    //     return 1;
    // else if (strcmp(src, "ALREADY CONNECT", 15) == 0)
    //     return 2;
    // else
    //     return -1;
    if (!strstr(src, "OK"))
        return 0;
    else if (!strstr(src, "ERROR"))
        return 1;
    else if (!strstr(src, "ALREADY"))
        return 2;
    else
        return -1;
}

void OSLIB_PLUS_Wifi_UDP_SendData(UART_HandleTypeDef *huart, uint8_t *data, uint32_t length)
{
    assert_param(length > 0 && length <= 2048);
    uprintf_to(&huart, "AT+CIPSEND=%hu\r\n", length);
    OSLIB_Uart_SendData(&huart, data, length);
    return 0;
}

extern osMessageQueueId_t WifiATCommandQueue;

static Wifi_AT_t atcmd;
// static char wifi_uart_tempbuf[RxBufferSize]; // FIXME:是否需要将数据复制缓冲区?
void UartWifiATTask(void *argument)
{
    UNUSED(argument);
    
    osStatus_t ret;
    for(;;)
    {
        osMessageQueueGet(WifiATCommandQueue, &atcmd, NULL, osWaitForever);
        assert_param(atcmd.request != NULL);
        assert_param(atcmd.waitfor != NULL);
        OSLIB_Uart_Printf(&wifi_huart, atcmd.request);
        ret = osSemaphoreAcquire(wifi_uart_rxsema, osWaitForever); // FIXME: 设置等待时间
        if (ret == osOK) {
            if (NULL != strstr(wifi_uart_rxbuf, atcmd.waitfor)) {
                // TODO: 检测成功, 接收下一条指令
            }
        }
        else if (ret == osErrorTimeout) {
            // FIXME: 超时处理
        }
    }
}

#endif

#include <string.h>
#include <stdio.h>

#include "ctrl_protocol.h"

extern osMessageQueueId_t CtrlRecvQueueHandle;
// extern osEventFlagsId_t ATCmdEventHandle;
extern osSemaphoreId_t ATCmdSemaHandle;

// #define ACE_FLAG_COMMAND    0x0001
// #define ACE_FLAG_RESPONSE   0x0002

static char ATRspBuf[RxBufferSize];

void _ATRecvTask(void *argument)
{
    UNUSED(argument);
    int datalen;
    char *colonptr;
    ctrl_prot_t *packbuf;
    for (;;)
    {
        osSemaphoreAcquire(UART1_RxSema, osWaitForever);
        if (0 == strncmp(UART1_TaskBuffer, "\r\n+IPD", 6)) {        // 前缀匹配
            datalen = strtol(UART1_TaskBuffer+7, &colonptr, 10);    // 得到报文长度
            if (datalen != 0) {
                // 处理接收到的报文
                // for (int i = 0; i < datalen; i++) {
                //     if (NULL != (packbuf = ctrl_recv_char_to_pack(colonptr[i+1]))) {
                //         osMessageQueuePut(CtrlRecvQueueHandle, &(packbuf), NULL, 0);
                //     }
                // }
                Info("[RX]%dB", datalen);  
            }
        }
        else {
            memcpy(ATRspBuf, UART1_TaskBuffer, RxBufferSize);
            // osEventFlagsSet(ACE_FLAG_RESPONSE);
            osSemaphoreRelease(ATCmdSemaHandle);
        }
    }
}

// #define ATCmdBuf_Size 4

// static ATCmd_t ATCmdBuf[ATCmdBuf_Size];
// static uint8_t ATCmdBuf_Wpos = 0;
// static uint8_t ATCmdBuf_Rpos = 0;
// // 当前任务未处理完, 缓冲起来

// void ATCmdTask(void *argument)
// {
//     UNUSED(argument);
//     uint32_t events;
//     for(;;)
//     {
//         events = osEventFlagsWait(ATCmdEventHandle, ACE_FLAG_RESPONSE|ACE_FLAG_COMMAND, osFlagsWaitAll, osWaitForever);
//         if (!(events & 0xFF000000)) {
//             if (events & ACE_FLAG_COMMAND) {
//                 // TODO: 发送命令
//                 memcpy()
//                 if ((ATCmdBuf_Wpos+1)%4 != ATCmdBuf_Rpos) {

//                 }

//             }
//             if (events & ACE_FLAG_RESPONSE) {
//                 // TODO: 接收回复
//             }
//         }
//     }
// }

// #define WIFI_ROLE_AP    0
// #define WIFI_ROLE_STA   1

#define WIFI_STATE_NOTREADY     0
#define WIFI_STATE_NOTCONNECT   1
#define WIFI_STATE_READY        2
static uint8_t WIFI_STATE = WIFI_STATE_NOTREADY;

int AT_APSTA_Connect(void)
{
    if (WIFI_STATE == WIFI_STATE_NOTREADY) {
        uint32_t ret = 0;
        // ret = osEventFlagsWait(ATCmdEventHandle, ACE_FLAG_RESPONSE, 15000);
        ret = osSemaphoreAcquire(ATCmdSemaHandle, 15000);
        
        // if (!(ret & 0xFF000000)) {
        if (ret == osOK) {
            Info("ATSTA_Connect: %s", ATRspBuf);
            if (strstr(ATRspBuf, "+STA") != NULL) {
                // WIFI_ROLE = WIFI_ROLE_STA;
                WIFI_STATE = WIFI_STATE_NOTCONNECT;
                return 0;
            }
            else if (strstr(ATRspBuf, "WIFI") != NULL) {
                // WIFI_ROLE = WIFI_ROLE_AP;
                WIFI_STATE = WIFI_STATE_NOTCONNECT;
                return 1;
            }
            // else
            //     Info("[E]ATSTA_Connect: %s", ATRspBuf);
        }
        else if (ret == osErrorTimeout) {
            return -2;
        }
    }
    return -1;
}

int AT_UDP_Connect(const char *remote_ip, uint16_t remote_port, uint16_t local_port)
{
    if (WIFI_STATE == WIFI_STATE_NOTCONNECT) {
        uint32_t ret = 0;
        OSLIB_Uart_Printf(&huart1, "AT+CIPSTART=\"UDP\",\"%s\",%hu,%hu\r\n", remote_ip, remote_port, local_port);
        // ret = osEventFlagsWait(ATCmdEventHandle, ACE_FLAG_RESPONSE, 5000);
        ret = osSemaphoreAcquire(ATCmdSemaHandle, 5000);

        // if (!(ret & 0xFF000000)) {
        if (ret == osOK) {
            Info("UDP_Connect: %s", ATRspBuf);
            if (strstr(ATRspBuf, "OK") != NULL) {
                WIFI_STATE = WIFI_STATE_READY;
                return 0;
            }
            else if (strstr(ATRspBuf, "Error") != NULL) {
                return 1;
            }
            else if (strstr(ATRspBuf, "ALREADY CONNECT")) {
                WIFI_STATE = WIFI_STATE_READY;
                return 2;   
            }
            // else
            //     Info("[E]UDP_Connect: %s", ATRspBuf);
        }
        else if (ret == osErrorTimeout) {
            return -2;
        }
    }
    return -1;
}

int AT_UDP_SendData(uint8_t *data, uint32_t length)
{
    if (WIFI_STATE == WIFI_STATE_READY) {
        uint32_t ret = 0;
        Info("AT_SendData: %s", ATRspBuf);
        OSLIB_Uart_Printf(&huart1, "AT+CIPSEND=%u\r\n", length);
        OSLIB_Uart_SendData(&huart1, data, length);
        while (1) {
            // osEventFlagsWait(ATCmdEventHandle, ACE_FLAG_RESPONSE, 5000);
            ret = osSemaphoreAcquire(ATCmdSemaHandle, 5000);

            Info("AT_SendData: %s", ATRspBuf);
            // if (!(ret & 0xFF000000)) {
            if (ret == osOK) {
                if (strstr(ATRspBuf, "SEND OK") != NULL) {
                    return 0;
                }
                else if (strstr(ATRspBuf, "ERROR")) {
                    return 1;
                }
                // else
                //     Info("[E]AT_SendData: %s", ATRspBuf);
            }
            else if (ret == osErrorTimeout) {
                return -2;
            }
        }
    }
    return -1;
}